package com.inspur.cloud.aspect;

import com.inspur.cloud.configuration.AmbariConfig;
import com.inspur.cloud.entity.dataspace.AuditLogEntity;
import com.inspur.cloud.entity.dataspace.UserThreadLocal;
import com.inspur.cloud.entity.dataspace.common.OpResult;
import com.inspur.cloud.service.dataspace.AuditLogService;
import com.inspur.cloud.util.ExceptionHelper;
import com.inspur.cloud.util.HttpUtil;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Aspect
@Component
public class ControllerAspect {

    private static Logger log = LoggerFactory.getLogger(ControllerAspect.class);

    @Autowired
    private AuditLogService auditLogService;

    @Autowired
    private AmbariConfig ambariConfig;

    @Pointcut("execution(* com.inspur.cloud.controller..*.*(..))")
    public void allController() {
    }

    @Pointcut("execution(* com.inspur.cloud.controller.AuditLogController.*(..))")
    public void auditController() {
    }
    @Pointcut("execution(* com.inspur.cloud.controller.VerifyCodeController.*(..))")
    public void verifyCodeController() {
    }

    @AfterReturning(pointcut = "allController() && !auditController() && !verifyCodeController()", returning = "returnValue")
    public void afterReturning(JoinPoint jp, OpResult returnValue) {
        try {

            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            String url = request.getRequestURI();
            if (!url.contains("/login") && "GET".equals(request.getMethod())) {
                return;
            }
            AuditLogEntity operationLog = new AuditLogEntity();
            //从ThreadLocal中获取用户名和id
            if (!StringUtils.isEmpty(UserThreadLocal.getValue("username"))) {
                operationLog.setLoginName(UserThreadLocal.getValue("username"));
            }
            if (!StringUtils.isEmpty(UserThreadLocal.getValue("userId"))) {
                operationLog.setUserId(Integer.parseInt(UserThreadLocal.getValue("userId")));
            }
            //获取client的ip
            operationLog.setRemoteIp(HttpUtil.getClientIP(request));

            operationLog.setRequestUrl(request.getRequestURL().toString());
            operationLog.setRequestMethod(request.getMethod());
            //获取参数
            String queryString = request.getQueryString();
            String requestBody = UserThreadLocal.getValue("requestBody");
            if (StringUtils.isEmpty(requestBody)) {
                operationLog.setParams(queryString);
            } else {
                operationLog.setParams(hidePass(requestBody));
            }
            //判断是否执行成功
            if (returnValue != null && returnValue.getCode() == 1) {
                if (StringUtils.isEmpty(returnValue.getMsg())) {
                    operationLog.setResult("成功");
                } else {
                    operationLog.setResult(returnValue.getMsg());
                }
            } else {
                operationLog.setResult(returnValue.getMsg());
            }
            //判断资源类型
            String resource = getResouceType(url);
            if (resource == null) {
                operationLog.setIsResource(false);
            } else {
                operationLog.setIsResource(true);
                operationLog.setResourceName(resource);
            }
            //获取服务器ip和名称
            String serverIp = ambariConfig.getAmbariUri();
            operationLog.setServerIp(serverIp.replace("8080", "8090"));
            operationLog.setServerName(System.getenv("HOSTMANE"));
            //operationLog.setServerName(address.getHostName());
            auditLogService.save(operationLog);
        } catch (Exception e) {
            log.error(ExceptionHelper.getExceptionDetail(e));
        }
    }

    private String getResouceType(String url) {
        if (url.contains("hdfs")) {
            return "hdfs";
        }
        if (url.contains("hive")) {
            return "hive";
        }
        if (url.contains("hbase")) {
            return "hbase";
        }
        if (url.contains("yarn")) {
            return "yarn";
        }
        if (url.contains("kafka")) {
            return "kafka";
        }
        return null;
    }

    //隐去日志中的密码
    private String hidePass(String params) {
        if (StringUtils.isEmpty(params)) {
            return params;
        }
        String[] list = params.split("\"");
        int length = list.length;
        if (length < 2) {
            return params;
        }
        for (int i = 0; i < length; i++) {
            if (list[i].contains("assword") && i + 2 < length) {
                list[i + 2] = "*******";
            }
        }
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            if (i != 0) {
                sb.append("\"");
            }
            sb.append(list[i]);
        }
        return sb.toString();
    }
}

